package cn.gok.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author shikundai
 * @date 2021/3/24
 * @time 11:43
 * @description: shiro的相关配置
 */
@Configuration
public class ShiroConfig {
    @Value("${spring.redis.host}")
    private String host;
    @Autowired
    private SessionDaoConfig sessionDaoConfig;
    /**
     * 凭证匹配器
     * （由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了）
     * HashedCredentialsMatcher说明：
     * 用户传入的token先经过shiroRealm的doGetAuthenticationInfo方法
     * 此时token中的密码为明文。
     * 再经由HashedCredentialsMatcher加密password与查询用户的结果password做对比。
     * new SimpleHash("SHA-256", password, null, 1024).toHex();
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher=new HashedCredentialsMatcher();
        //加密算法
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        //加密1000次
        hashedCredentialsMatcher.setHashIterations(1000);
        return hashedCredentialsMatcher;
    }
  /**
   * 描述：创建Realm
   * @author shikundai
   * @date 2021/3/24
   * @time 11:45
   */
    @Bean
    public ShiroRealm shiroRealm(){
        ShiroRealm shiroRealm=new ShiroRealm();
        //关闭缓存
        shiroRealm.setAuthenticationCachingEnabled(false);
        //设置加密方式
        shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return shiroRealm;
    }
    /**
     * 描述：创建securityManager
     * @author shikundai
     * @date 2021/3/24
     * @time 11:46
     */
    @Bean
    public DefaultWebSecurityManager securityManager(ShiroRealm shiroRealm){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm);

        //自定义的session规则
        SessionConfig sessionConfig=new SessionConfig();
        securityManager.setSessionManager(sessionConfig);

//        sessionConfig.setSessionDAO(sessionDaoConfig);

//         RedisSessionDAO redisSessionDAO=new RedisSessionDAO();
//         RedisManager redisManager=new RedisManager();
//         redisManager.setHost(host);
//         redisSessionDAO.setRedisManager(redisManager);
//         sessionConfig.setSessionDAO(redisSessionDAO);




        return securityManager;
    }




    /**
     * 描述：创建过滤器
     * @author shikundai
     * @date 2021/3/24
     * @time 11:43
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilter=new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);

        //设置登录页面
        shiroFilter.setLoginUrl("/login.html");
        //设置放行的页面
        Map<String,String> filterChain=new HashMap<>();
        filterChain.put("/logout", "anon");
        filterChain.put("/login", "anon");
        filterChain.put("/register", "anon");
        filterChain.put("/res/**", "anon");
        filterChain.put("/test/**","anon");
        //认证访问
        filterChain.put("/**" , "authc");
        shiroFilter.setFilterChainDefinitionMap(filterChain);
        return shiroFilter;
    }


    /**
     * 开启Shiro注解(如@RequiresRoles,@RequiresPermissions),
     * 需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
     * 配置以下两个bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
    /**
     * 描述：开启aop注解支持
     * @author shikundai
     * @date 2021/3/24
     * @time 11:47
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }


}
